/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JTestFrame.java
 *
 * Created on Oct 19, 2009, 12:11:02 PM
 */

package dasher.ui;

import dasher.utils.TestWorker;
import dasher.utils.TestWorker.DoneEvent;
import dasher.utils.TestWorker.PublishEvent;
import dasher.utils.TestWorker.WorkerListener;
import java.awt.Frame;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import org.jdesktop.swingworker.SwingWorker;
import org.junit.Test;

/**
 *
 * @author joshua
 */
public class JTestFrame<T> extends javax.swing.JFrame implements PropertyChangeListener, TestWorker.WorkerListener<T,String> {

    Logger log = Logger.getLogger(JTestFrame.class.getCanonicalName());

    QueueWorker<T> worker = new QueueWorker<T>();
    
    @Test
    public void testFrameStateSupported() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        String f = "Supports %s: %s\n";
        System.out.format(f, "MAXIMIZED_BOTH", toolkit.isFrameStateSupported(Frame.MAXIMIZED_BOTH));
        System.out.format(f, "MAXIMIZED_HORIZ", toolkit.isFrameStateSupported(Frame.MAXIMIZED_HORIZ));
        System.out.format(f, "MAXIMIZED_VERT", toolkit.isFrameStateSupported(Frame.MAXIMIZED_VERT));
    }

    @Test
    public void testFrame() throws InterruptedException {
        (new JTestFrame()).openAndWait();
    }

    public void openAndWait() throws InterruptedException {
        final JFrame form = this;
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                form.setVisible(true);
            }
        });
        waitUntilClosed();
    }

    public void waitUntilClosed() throws InterruptedException {
        Thread.sleep(1000);
        while (isVisible()) {
            Thread.sleep(200);
        }
    }

    /** Creates new form JTestFrame */
    public JTestFrame() {
        initComponents();
    }

    public void addWorker(TestWorker<T,String> worker) {
        this.worker.add(worker);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea = new javax.swing.JTextArea();
        jPanel1 = new javax.swing.JPanel();
        jButtonCancel = new javax.swing.JButton();
        jButtonStart = new javax.swing.JButton();
        jProgressBar = new javax.swing.JProgressBar();
        jButtonMax = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextArea.setColumns(20);
        jTextArea.setEditable(false);
        jTextArea.setRows(5);
        jScrollPane1.setViewportView(jTextArea);

        jButtonCancel.setText("Cancel");
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jButtonStart.setText("Start");
        jButtonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartActionPerformed(evt);
            }
        });

        jButtonMax.setText("Maximize");
        jButtonMax.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonMaxActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                        .add(jProgressBar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButtonStart)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButtonCancel))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jButtonMax))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
                    .add(jProgressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jButtonStart)
                    .add(jButtonCancel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jButtonMax)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartActionPerformed
        jButtonStart.setEnabled(false);
        worker.execute();
    }//GEN-LAST:event_jButtonStartActionPerformed

    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
        if (worker == null || worker.isDone() || worker.isCancelled())
            setVisible(false);
        else {
            worker.cancel(true);
        }
    }//GEN-LAST:event_jButtonCancelActionPerformed

    private void jButtonMaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonMaxActionPerformed
        setExtendedState(JFrame.MAXIMIZED_BOTH);
    }//GEN-LAST:event_jButtonMaxActionPerformed

    public void format(String format, Object... args) {
        jTextArea.append(String.format(format, args));
    }
    public void println(String msg) {
        jTextArea.append(msg + "\n");
    }

//    @Test
//    public void testProgress() {
//        java.awt.EventQueue.invokeLater(new Runnable() {
//            public void run() {
//                new JTestFrame().setVisible(true);
//            }
//        });
//    }
//
//    /**
//    * @param args the command line arguments
//    */
//    public static void main(String args[]) {
//        java.awt.EventQueue.invokeLater(new Runnable() {
//            public void run() {
//                new JTestFrame().setVisible(true);
//            }
//        });
//    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JButton jButtonMax;
    private javax.swing.JButton jButtonStart;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea;
    // End of variables declaration//GEN-END:variables

    public void propertyChange(PropertyChangeEvent evt) {
        if ("progress".equals(evt.getPropertyName())) {
            jProgressBar.setValue((Integer) evt.getNewValue());
//            println("Progress: " + evt.getNewValue() + "%");
        } else if ("state".equals(evt.getPropertyName())) {
            switch ((SwingWorker.StateValue) evt.getNewValue()) {
                case DONE:
                    jButtonCancel.setText("Quit");
                    println("Done.");
                    break;
            }
        }
    }

    public void workerDone(DoneEvent<T, String> event) {
        println("Worker done.");
    }

    public void workerPublish(PublishEvent<T, String> event) {
        println("workerPublish");
        for (String line : event.getChunks())
            println(line);
    }

    static class QueueWorker<T> extends TestWorker<Map<TestWorker<T,String>,T>,String>
                                implements PropertyChangeListener,
                                            WorkerListener<T,String> {
        Queue<TestWorker<T,String>> queue = new LinkedList<TestWorker<T, String>>();
        int progess = 0, total;

        public void add(TestWorker<T,String> worker) {
            queue.add(worker);
        }

        @Override
        protected Map<TestWorker<T,String>,T> doInBackground() throws Exception {
            Map<TestWorker<T,String>,T> result = new HashMap<TestWorker<T, String>, T>(queue.size());
            for (TestWorker<T,String> worker : queue) {
                worker.addPropertyChangeListener(this);
            }
            return result;
        }

        public void propertyChange(PropertyChangeEvent evt) {
            if ("progress".equals(evt.getPropertyName())) {
                progess += (Integer) evt.getNewValue();
                setProgress((int) (100.0 * progess / total));
            }
        }

        public void workerDone(DoneEvent<T, String> event) {
            publish(String.format("Done: %s\n", event.getWorker()));
        }

        public void workerPublish(PublishEvent<T, String> event) {
            publish((String[]) event.getChunks().toArray());
        }

    }
}
